package org.unt.jdbc;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

public class MyDataSource {

	private static DataSource dataSource = null;
	private static GenericObjectPool connectionPool = null;

	public static Connection getConnection() throws SQLException {

		long millis = System.currentTimeMillis();

		Connection connection = dataSource.getConnection();

		System.out.println(Thread.currentThread().getName() + " connection took " + (System.currentTimeMillis() - millis) + " millis\t" + statusToString());

		return connection;
	}

	/**
	 * Initialize the pool of JDBC connections
	 * 
	 * @param poolSize
	 *            Max amount of active connections available for service database calls
	 * @return The total time it took the initialization (millis)
	 * @throws SQLException
	 */
	public static int init(String driver, String url, String user, String password, int poolSize) throws SQLException {

		long time = System.currentTimeMillis();

		try {
			Class.forName(driver).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		connectionPool = new GenericObjectPool();
		connectionPool.setMaxActive(poolSize);

		ConnectionFactory cf = new DriverManagerConnectionFactory(url, user, password);
		new PoolableConnectionFactory(cf, connectionPool, null, null, false, false);

		dataSource = new PoolingDataSource(connectionPool);

		// Initialize all connections for speed up later calls
		Connection[] conn = new Connection[poolSize];
		for (int i = 0; i < poolSize; i++) {
			conn[i] = dataSource.getConnection();
		}
		for (int i = 0; i < poolSize; i++) {
			conn[i].close();
		}

		return (int) (System.currentTimeMillis() - time);
	}

	/** Get maxActive, numActive, numIdle */
	public static int[] status() {
		return new int[] { connectionPool.getMaxActive(), connectionPool.getNumActive(), connectionPool.getNumIdle() };
	}

	public static String statusToString() {
		return connectionPool.getMaxActive() + " " + connectionPool.getNumActive() + " " + connectionPool.getNumIdle();
	}
}
